//
//  CheckCardUtils.m
//  PokerHandUp
//
//  Created by psvn047 on 6/22/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "CheckCardUtils.h"
#import "Card.h"
@implementation CheckCardUtils
+ (NSArray*) sortRankCards: (NSArray*) array ascending:(BOOL) isAscending
{
    NSSortDescriptor * descriptor = [[[NSSortDescriptor alloc] initWithKey:@"rank" ascending:isAscending] autorelease];
    NSArray * sortDescriptors = [NSArray arrayWithObject:descriptor];
    NSArray * sortedArray = [array sortedArrayUsingDescriptors:sortDescriptors];
    return sortedArray;
}
+ (NSArray*) sortSuitCards: (NSArray*) array ascending:(BOOL) isAscending
{
    NSSortDescriptor * descriptor = [[[NSSortDescriptor alloc] initWithKey:@"suit" ascending:isAscending] autorelease];
    NSArray * sortDescriptors = [NSArray arrayWithObject:descriptor];
    NSArray * sortedArray = [array sortedArrayUsingDescriptors:sortDescriptors];
    return sortedArray;
}
// Array is seven cards
+ (NSArray*) checkFlush: (NSArray*) array
{
    if([array count] < 5)
    {
        return NULL;
    }
    NSArray * sortArray = [CheckCardUtils sortSuitCards:array ascending:NO];
    //[CheckCardUtils debugCards:sortArray];
    NSMutableArray * clubs = [NSMutableArray array];
    NSMutableArray * diamonds = [NSMutableArray array];
    NSMutableArray * hearts = [NSMutableArray array];
    NSMutableArray * spades = [NSMutableArray array];
    for(Card * card in sortArray)
    {
        if(card.suit == kCardSuitHearts)
        {
            [hearts addObject:card];
        }
        else if(card.suit == kCardSuitDiamonds)
        {
             [diamonds addObject:card];
        }
        else if(card.suit == kCardSuitClubs)
        {
             [clubs addObject:card];
        }
        else if(card.suit == kCardSuitSpades)
        {
             [spades addObject:card];
        }
    }
    
    if([hearts count] >= 5)
    {
        return [CheckCardUtils sortRankCards:hearts ascending:NO];
    }
    else if([diamonds count] >= 5)
    {
        return [CheckCardUtils sortRankCards:diamonds ascending:NO];
    }
    else if([clubs count] >= 5)
    {
        return [CheckCardUtils sortRankCards:clubs ascending:NO];
    }
    else if([spades count] >= 5)
    {
        return [CheckCardUtils sortRankCards:spades ascending:NO];
    }
    return NULL;
}
+(void) debugCards:(NSArray*) array
{
    [CheckCardUtils debugCards:array tips:@""];
}
+(void) debugCards:(NSArray*) array tips:(NSString*) tips
{
    if (array != nil && [array count]) {
        NSLog(@"========== Start %@ =========",tips);
        for(Card* card in array)
        {
            
            NSLog(@"**  %@",[self formatStringCard:card]);
        }
        NSLog(@"========== End %@ ===========",tips);

    }
}

// array is 7 cards
+ (NSArray*) checkStraight: (NSArray*) array
{
    if([array count] < 5)
    {
        return NULL;
    }
    NSArray * sortArray = [CheckCardUtils sortRankCards:array ascending:NO];
    //[CheckCardUtils debugCards:sortArray];
    Card * first;
    Card * second;
    Card* isAceCard = NULL;
    NSMutableArray* straight5432A = nil;
    NSMutableArray * result = [NSMutableArray array];
    for(int i=0; i<[sortArray count]; i++)
    {
        first = (Card*) [sortArray objectAtIndex:i];
        [result addObject:first];
        if([first rank] == kCardRankAce)
        {
            isAceCard = first;
        }
        for(int j=i+1; j<[sortArray count]; j++)
        {
            second = (Card*) [sortArray objectAtIndex:j];
            if([first rank] == [second rank] + 1)
            {
                [result addObject:second];
                first = second;
                if([result count]== 5)
                {
                    return result;
                }
            }
            else if ([first rank] == [second rank]) 
            {
                first = second;
            }
            else {
                j = [sortArray count];
            }
        }
        // reset result and check straight5432A
        if([result count] == 4 && isAceCard != NULL) // new i
        {
            Card* tmpCard = (Card*) [result objectAtIndex:0];
            if([tmpCard rank] == kCardRank5)
            {
                [result addObject:isAceCard];
                straight5432A = [result mutableCopy];
            }
        }
        [result removeAllObjects];
    }
    
    if(straight5432A != nil) //Check 5432A straight
    {
        return straight5432A;
    }
    return NULL;
}
// Array is flush
+ (NSArray*) checkStraightFlush: (NSArray*) array 
{
    return [CheckCardUtils checkStraight:array];
}
// Array is Flush
+ (NSArray*) checkRoyalFlush: (NSArray*) array
{
    if([array count] < 5)
    {
        return NULL;
    }
    NSArray * sortArray = [CheckCardUtils sortRankCards:array ascending:NO];
    // check Ace
    Card * aceCard = [sortArray objectAtIndex:0];
    Card * kingCard = [sortArray objectAtIndex:1];
    Card * queenCard = [sortArray objectAtIndex:2];
    Card * jackCard = [sortArray objectAtIndex:3];
    Card * tenCard = [sortArray objectAtIndex:4];
    if ([aceCard rank] == kCardRankAce && [kingCard rank] == kCardRankKing && [queenCard rank] == kCardRankQueen && [jackCard rank] == kCardRankJack && [tenCard rank] == kCardRank10) 
    {
        return [sortArray subarrayWithRange:NSMakeRange(0, 5)];
    }
    
    return NULL;
}
+ (NSString*) formatStringCard:(Card*) card
{
    NSString * rank;
    NSString * suit;
    if(card.suit == kCardSuitHearts)
    {
        suit = @"Heart";
    }
    else if(card.suit == kCardSuitDiamonds)
    {
        suit = @"Diamond";
    }
    else if(card.suit == kCardSuitClubs)
    {
        suit = @"Club";
    }
    else if(card.suit == kCardSuitSpades)
    {
        suit = @"Spade";
    }
    
    if(card.rank == kCardRankAce)
    {
        rank = @"Ace";
    }
    else if(card.rank == kCardRankKing)
    {
        rank = @"King";
    }
    else if(card.rank == kCardRankQueen)
    {
        rank = @"Queen";
    }
    else if(card.rank == kCardRankJack)
    {
        rank = @"Jack";
    }
    else if(card.rank == kCardRank10)
    {
        rank = @"10";
    }
    else if(card.rank == kCardRank9)
    {
        rank = @"9";
    }
    else if(card.rank == kCardRank8)
    {
        rank = @"8";
    }
    else if(card.rank == kCardRank7)
    {
        rank = @"7";
    }
    else if(card.rank == kCardRank6)
    {
        rank = @"6";
    }
    else if(card.rank == kCardRank5)
    {
        rank = @"5";
    }
    else if(card.rank == kCardRank4)
    {
        rank = @"4";
    }
    else if(card.rank == kCardRank3)
    {
        rank = @"3";
    }
    else if(card.rank == kCardRank2)
    {
        rank = @"2";
    }
    return [NSString stringWithFormat:@"%@ %@", rank,suit];
}
+ (NSArray*) checkFourOfAKind: (StatisticCards*) statCards
{
    if([statCards.aceCards count] == 4)
    {
        return [statCards.aceCards mutableCopy];
    }
    else  if([statCards.kingCards count] == 4)
    {
        return [statCards.kingCards mutableCopy];
    }
    else  if([statCards.queenCards count] == 4)
    {
        return [statCards.queenCards mutableCopy];
    }
    else  if([statCards.jackCards count] == 4)
    {
        return [statCards.jackCards mutableCopy];
    }
    else  if([statCards.tenCards count] == 4)
    {
        return [statCards.tenCards mutableCopy];
    }
    else  if([statCards.nineCards count] == 4)
    {
        return [statCards.nineCards mutableCopy];
    }
    else  if([statCards.eightCards count] == 4)
    {
        return [statCards.eightCards mutableCopy];
    } 
    else  if([statCards.sevenCards count] == 4)
    {
        return [statCards.sevenCards mutableCopy];
    }
    else  if([statCards.sixCards count] == 4)
    {
        return [statCards.sixCards mutableCopy];
    }
    else  if([statCards.fiveCards count] == 4)
    {
        return [statCards.fiveCards mutableCopy];
    }
    else  if([statCards.fourCards count] == 4)
    {
        return [statCards.fourCards mutableCopy];
    }
    else  if([statCards.threeCards count] == 4)
    {
        return [statCards.threeCards mutableCopy];
    }
    else  if([statCards.twoCards count] == 4)
    {
        return [statCards.twoCards mutableCopy];
    }
    return NULL;
}
+ (NSArray*) checkFullHouse: (StatisticCards*) statCards
{
    NSMutableArray * searchMaxPair; 
    NSMutableArray * bestCards = NULL; 
    if([statCards.aceCards count] == 3)
    {
        bestCards = [statCards.aceCards mutableCopy];
    }
    else  if([statCards.kingCards count] == 3)
    {
        bestCards = [statCards.kingCards mutableCopy];
    }
    else  if([statCards.queenCards count] == 3)
    {
        bestCards = [statCards.queenCards mutableCopy];
    }
    else  if([statCards.jackCards count] == 3)
    {
        bestCards = [statCards.jackCards mutableCopy];
    }
    else  if([statCards.tenCards count] == 3)
    {
        bestCards = [statCards.tenCards mutableCopy];
    }
    else  if([statCards.nineCards count] == 3)
    {
        bestCards = [statCards.nineCards mutableCopy];
    }
    else  if([statCards.eightCards count] == 3)
    {
        bestCards = [statCards.eightCards mutableCopy];
    } 
    else  if([statCards.sevenCards count] == 3)
    {
        bestCards = [statCards.sevenCards mutableCopy];
    }
    else  if([statCards.sixCards count] == 3)
    {
        bestCards = [statCards.sixCards mutableCopy];
    }
    else  if([statCards.fiveCards count] == 3)
    {
        bestCards = [statCards.fiveCards mutableCopy];
    }
    else  if([statCards.fourCards count] == 3)
    {
        bestCards = [statCards.fourCards mutableCopy];
    }
    else  if([statCards.threeCards count] == 3)
    {
        bestCards = [statCards.threeCards mutableCopy];
    }
    else  if([statCards.twoCards count] == 3)
    {
        bestCards = [statCards.twoCards mutableCopy];
    }
    //check result
    if(bestCards != NULL)
    {
        searchMaxPair = (NSMutableArray*)[CheckCardUtils checkMaxPair:statCards except:bestCards];
        if(searchMaxPair != NULL)
        {
            [bestCards addObjectsFromArray:searchMaxPair];
            return bestCards;
        }
    }
    return NULL;
}
+ (NSArray*) checkMaxPair: (StatisticCards*) statCards except:(NSArray*) except
{
    NSArray* valueArr;
    Card* first;
    for (int i = 0; i < [statCards.fullCards count]; i++) {
        valueArr = [statCards.fullCards objectAtIndex:i];
        if([valueArr count] >= 2)
        {
            first = (Card*) [valueArr objectAtIndex:0];
            if(except)
            {
                for(int j=0; j < [except count]; j++)
                {
                    Card* card = (Card*) [except objectAtIndex:j];
                    if([first rank] != [card rank])
                    {
                        return [valueArr subarrayWithRange:NSMakeRange(0, 2)];
                    }
                }
            }
            else {
                return [valueArr subarrayWithRange:NSMakeRange(0, 2)];
            }
        }
    }
    return NULL;
}
+ (NSArray*) checkMaxCard: (StatisticCards*) statCards rank:(int) rank except:(NSArray*) except
{
    NSArray* valueArr;
    Card* first;
    NSMutableArray* resultArr = [NSMutableArray array];
    for (int i = 0; i < [statCards.fullCards count]; i++) {
        valueArr = [statCards.fullCards objectAtIndex:i];
        if([valueArr count] >= 1)
        {
           first = (Card*) [valueArr objectAtIndex:0];
           if(except)
            {
                BOOL checkCard = true;
                for(int j=0; j < [except count]; j++)
                {
                    Card* card = (Card*) [except objectAtIndex:j];
                    if([first rank] == [card rank])
                    {
                        j = [except count];
                        checkCard = false;
                    }
                }
                
                if(checkCard)
                {
                     [resultArr addObject:first];
                }
            }
           else {
               [resultArr addObject:first];
           }
        }
        if([resultArr count] == rank)
        {
            return [resultArr mutableCopy];
        }
              
   
    }
    return NULL;
}
+ (NSArray*) checkThreeOfAKind: (StatisticCards*) statCards
{
    if([statCards.aceCards count] == 3)
    {
        return [statCards.aceCards mutableCopy];
    }
    else  if([statCards.kingCards count] == 3)
    {
        return [statCards.kingCards mutableCopy];
    }
    else  if([statCards.queenCards count] == 3)
    {
        return [statCards.queenCards mutableCopy];
    }
    else  if([statCards.jackCards count] == 3)
    {
        return [statCards.jackCards mutableCopy];
    }
    else  if([statCards.tenCards count] == 3)
    {
        return [statCards.tenCards mutableCopy];
    }
    else  if([statCards.nineCards count] == 3)
    {
        return [statCards.nineCards mutableCopy];
    }
    else  if([statCards.eightCards count] == 3)
    {
        return [statCards.eightCards mutableCopy];
    } 
    else  if([statCards.sevenCards count] == 3)
    {
        return [statCards.sevenCards mutableCopy];
    }
    else  if([statCards.sixCards count] == 3)
    {
        return [statCards.sixCards mutableCopy];
    }
    else  if([statCards.fiveCards count] == 3)
    {
        return [statCards.fiveCards mutableCopy];
    }
    else  if([statCards.fourCards count] == 3)
    {
        return [statCards.fourCards mutableCopy];
    }
    else  if([statCards.threeCards count] == 3)
    {
        return [statCards.threeCards mutableCopy];
    }
    else  if([statCards.twoCards count] == 3)
    {
        return [statCards.twoCards mutableCopy];
    }

    return NULL;
}
+ (NSArray*) checkTwoPair: (StatisticCards*) statCards
{
    NSMutableArray * result = [NSMutableArray array];
    NSMutableArray * firstArr = nil;
    NSMutableArray * secondArr = nil;
    for(NSMutableArray* array in statCards.fullCards)
    {
        Card * firstCard;
        Card * secondCard;
        if([array count] == 2)
        {
            if(firstArr == NULL)
            {
                firstArr = array;
            }
            else 
            {
                firstCard = (Card*) [firstArr objectAtIndex:0];
                secondCard = (Card*) [array objectAtIndex:0];
                if(secondArr == NULL)
                {
                    if([firstCard rank] < [secondCard rank])
                    {
                        secondArr = firstArr;
                        firstArr = array;
                    }
                    else 
                    {
                        secondArr = array;
                    }

                }
                else 
                {
                    if([firstCard rank] < [secondCard rank])
                    {
                        secondArr = firstArr;
                        firstArr = array;
                    }
                    else 
                    {
                        firstCard = (Card*) [secondArr objectAtIndex:0];
                        if([firstCard rank] < [secondCard rank])
                        {
                            secondArr = array;
                        }
                    }

                }
            }
        }
        
        if(firstArr != nil && [firstArr count] && secondCard != nil && [secondArr count])
        {
            [result addObjectsFromArray:[firstArr mutableCopy]];
            [result addObjectsFromArray:[secondArr mutableCopy]];
            return result;
        }
    }
    
    return NULL;
}
+ (NSArray*) checkPair: (StatisticCards*) statCards
{
    if([statCards.aceCards count] == 2)
    {
        return [statCards.aceCards mutableCopy];
    }
    else  if([statCards.kingCards count] == 2)
    {
        return [statCards.kingCards mutableCopy];
    }
    else  if([statCards.queenCards count] == 2)
    {
        return [statCards.queenCards mutableCopy];
    }
    else  if([statCards.jackCards count] == 2)
    {
        return [statCards.jackCards mutableCopy];
    }
    else  if([statCards.tenCards count] == 2)
    {
        return [statCards.tenCards mutableCopy];
    }
    else  if([statCards.nineCards count] == 2)
    {
        return [statCards.nineCards mutableCopy];
    }
    else  if([statCards.eightCards count] == 2)
    {
        return [statCards.eightCards mutableCopy];
    } 
    else  if([statCards.sevenCards count] == 2)
    {
        return [statCards.sevenCards mutableCopy];
    }
    else  if([statCards.sixCards count] == 2)
    {
        return [statCards.sixCards mutableCopy];
    }
    else  if([statCards.fiveCards count] == 2)
    {
        return [statCards.fiveCards mutableCopy];
    }
    else  if([statCards.fourCards count] == 2)
    {
        return [statCards.fourCards mutableCopy];
    }
    else  if([statCards.threeCards count] == 2)
    {
        return [statCards.threeCards mutableCopy];
    }
    else  if([statCards.twoCards count] == 2)
    {
        return [statCards.twoCards mutableCopy];
    }
    return NULL;
}
+ (NSArray*) checkHighCard: (NSArray*) array rank:(int) rank
{
    if([array count] < rank)
    {
        return NULL;
    }
    NSArray * sortArray = [CheckCardUtils sortRankCards:array ascending:NO];
    
    return [sortArray subarrayWithRange:NSMakeRange(0, rank)];
}
+(BestCardsInfo*) checkBestCard:(NSArray*) array
{
    StatisticCards * statCards;
    statCards = [[[StatisticCards alloc] init] autorelease];
    [statCards parseCards:array];
    BestCardsInfo* bestCardsInfo = [[BestCardsInfo alloc] init];
    NSArray* bestMaxCards;
    NSMutableArray * fullCard = [NSMutableArray array];
    NSArray* checkFourOfAKindArr = [CheckCardUtils checkFourOfAKind:statCards];
    // If are FourOfKind Or FullHouse, We could not have Flush Or Straight
    if(checkFourOfAKindArr != NULL) // If are FourOfAKind
    {
        bestCardsInfo.rankBestHank = kFourOfAKind;
        bestMaxCards = [CheckCardUtils checkMaxCard:statCards rank:1 except:checkFourOfAKindArr];
        [fullCard addObjectsFromArray:checkFourOfAKindArr];
        [fullCard addObjectsFromArray:bestMaxCards];
        bestCardsInfo.bestCards = [fullCard mutableCopy];
        return bestCardsInfo;
    }
    else // If are not FourOfAKind
    {
        NSArray* checkFullHouseArr = [CheckCardUtils checkFullHouse:statCards];
        if(checkFullHouseArr != NULL) // If are not FullHouse
        {
            bestCardsInfo.rankBestHank = kFullHouse;
            bestCardsInfo.bestCards = checkFullHouseArr;
            return bestCardsInfo;

        }
    }
    // Check Flush
    NSArray* checkFlushArr = [CheckCardUtils checkFlush:array];
    if(checkFlushArr != NULL) // if are Flush
    {
        NSArray*checkRoyalFlushArr = [CheckCardUtils checkRoyalFlush:checkFlushArr];
        if(checkRoyalFlushArr != NULL) // if are RoyalFlush
        {
            bestCardsInfo.rankBestHank = kRoyalFlush;
            bestCardsInfo.bestCards = [checkRoyalFlushArr subarrayWithRange:NSMakeRange(0, 5)];
            return bestCardsInfo;
        }
        else // if are not RoyalFlush
        {
            NSArray*checkStraightFlushArr= [CheckCardUtils checkStraightFlush:checkFlushArr];
            if(checkStraightFlushArr != NULL) // If are StraightFlush
            {
                bestCardsInfo.rankBestHank = kStraightFlush;
                bestCardsInfo.bestCards = [checkStraightFlushArr subarrayWithRange:NSMakeRange(0, 5)];
                return bestCardsInfo;
            }
            else // If are StraightFlush
            {
                bestCardsInfo.rankBestHank = kFlush;
                bestCardsInfo.bestCards = [checkFlushArr subarrayWithRange:NSMakeRange(0, 5)];
                return bestCardsInfo;
            }
        }
    }
    else // If are not Flush --- We check Straight
    {
        NSArray*checkStraightArr = [CheckCardUtils checkStraight:array];
        if(checkStraightArr != NULL) // If are Straight
        {
            bestCardsInfo.rankBestHank = kStraight;
            bestCardsInfo.bestCards = checkStraightArr;
            return bestCardsInfo;
        }
        else // If are not Straight
        {
            NSArray* checkThreeOfAKind = [CheckCardUtils checkThreeOfAKind:statCards];
            if(checkThreeOfAKind != NULL) // If are ThreeOfAKind
            {
                bestCardsInfo.rankBestHank = kThreeOfAKind;
                bestMaxCards = [CheckCardUtils checkMaxCard:statCards rank:2 except:checkThreeOfAKind];
                [fullCard addObjectsFromArray:checkThreeOfAKind];
                [fullCard addObjectsFromArray:bestMaxCards];
                bestCardsInfo.bestCards = [fullCard mutableCopy];
                return bestCardsInfo;
            }
            else // If are not ThreeOfAKind
            {
                NSArray* checkTwoPair = [CheckCardUtils checkTwoPair:statCards];
                if(checkTwoPair !=NULL) // If are TwoPair
                {
                    bestCardsInfo.rankBestHank = kTwoPair;
                    bestMaxCards = [CheckCardUtils checkMaxCard:statCards rank:1 except:checkTwoPair];
                    [fullCard addObjectsFromArray:checkTwoPair];
                    [fullCard addObjectsFromArray:bestMaxCards];
                    bestCardsInfo.bestCards = [fullCard mutableCopy];
                    return bestCardsInfo;
                }
                else // If are not TwoPair
                {
                    NSArray*checkPair = [CheckCardUtils checkPair:statCards];
                    if(checkPair != NULL) // If are Pair
                    {
                        bestCardsInfo.rankBestHank = kPair;
                        bestMaxCards = [CheckCardUtils checkMaxCard:statCards rank:3 except:checkPair];
                        [fullCard addObjectsFromArray:checkPair];
                        [fullCard addObjectsFromArray:bestMaxCards];
                        bestCardsInfo.bestCards = [fullCard mutableCopy];

                        return bestCardsInfo;
                    }
                    else // If are not Pair
                    {
                        NSArray* sortArray = [CheckCardUtils sortRankCards:array ascending:NO];
                        bestCardsInfo.rankBestHank = kHighCard;
                        bestCardsInfo.bestCards = [sortArray subarrayWithRange:NSMakeRange(0, 5)];
                        return bestCardsInfo;
                    }
                }
            }
        }
    }
    
    return  NULL;
}
@end

@implementation StatisticCards
@synthesize twoCards;
@synthesize threeCards;
@synthesize fourCards;
@synthesize fiveCards;
@synthesize sixCards;
@synthesize sevenCards;
@synthesize eightCards;
@synthesize nineCards;
@synthesize tenCards;
@synthesize jackCards;
@synthesize queenCards;
@synthesize kingCards;
@synthesize aceCards;

@synthesize clubCards;
@synthesize spadeCards;
@synthesize heartCards;
@synthesize diamondCards;

@synthesize fullCards;

-(void) parseCards:(NSArray*) array
{
    // init arrays
    twoCards = [NSMutableArray array];
    threeCards = [NSMutableArray array];
    fourCards = [NSMutableArray array];
    fiveCards = [NSMutableArray array];
    sixCards = [NSMutableArray array];
    sevenCards = [NSMutableArray array];
    eightCards = [NSMutableArray array];
    nineCards = [NSMutableArray array];
    tenCards = [NSMutableArray array];
    jackCards = [NSMutableArray array];
    queenCards = [NSMutableArray array];
    kingCards = [NSMutableArray array];
    aceCards = [NSMutableArray array];
    
    clubCards = [NSMutableArray array];
    spadeCards = [NSMutableArray array];
    heartCards = [NSMutableArray array];
    diamondCards = [NSMutableArray array];
    
    
    fullCards = [NSMutableArray array];
    [fullCards addObject:aceCards];
    [fullCards addObject:kingCards];
    [fullCards addObject:queenCards];
    [fullCards addObject:jackCards];
    [fullCards addObject:tenCards];
    [fullCards addObject:nineCards];
    [fullCards addObject:eightCards];
    [fullCards addObject:sevenCards];
    [fullCards addObject:sixCards];
    [fullCards addObject:fiveCards];
    [fullCards addObject:fourCards];
    [fullCards addObject:threeCards];
    [fullCards addObject:twoCards];

    // parse suit
    for(Card* card in array)
    {
        if ([card suit] == kCardSuitHearts) {
            [heartCards addObject:card];
        }
        else if ([card suit] == kCardSuitDiamonds) {
            [diamondCards addObject:card];
        }
        else if ([card suit] == kCardSuitClubs) {
            [clubCards addObject:card];
        }
        else if ([card suit] == kCardSuitSpades) {
            [spadeCards addObject:card];
        }
    }
    // parse rank
    for(Card* card in array)
    {
        if ([card rank] == kCardRank2) {
            [twoCards addObject:card];
        }
        else if ([card rank] == kCardRank3) {
            [threeCards addObject:card];
        }
        else if ([card rank] == kCardRank4) {
            [fourCards addObject:card];
        }
        else if ([card rank] == kCardRank5) {
            [fiveCards addObject:card];
        }
        else if ([card rank] == kCardRank6) {
            [sixCards addObject:card];
        }
        else if ([card rank] == kCardRank7) {
            [sevenCards addObject:card];
        }
        else if ([card rank] == kCardRank8) {
            [eightCards addObject:card];
        }
        else if ([card rank] == kCardRank9) {
            [nineCards addObject:card];
        }
        else if ([card rank] == kCardRank10) {
            [tenCards addObject:card];
        }
        else if ([card rank] == kCardRankJack) {
            [jackCards addObject:card];
        }
        else if ([card rank] == kCardRankQueen) {
            [queenCards addObject:card];
        }
        else if ([card rank] == kCardRankKing) {
            [kingCards addObject:card];
        }
        else if ([card rank] == kCardRankAce) {
            [aceCards addObject:card];
        }
    }
}
-(void) dealloc
{
    [super dealloc];
}
@end
@implementation BestCardsInfo
@synthesize bestCards;
@synthesize rankBestHank;
-(ResultCompareCards) compareBestCard:(BestCardsInfo*) bestCardsInfo
{
    if(rankBestHank > bestCardsInfo.rankBestHank) // win
    {
        return rCompareWin;
    }
    else if (rankBestHank < bestCardsInfo.rankBestHank) // close
    {
        return rCompareLose;
    }
    else // equal ranks
    {
        if(rankBestHank == kHighCard)
        {
            return [self calculateHighCard:bestCards rivalArray:bestCardsInfo.bestCards];
        }
        else if(rankBestHank == kPair)
        {
           return [self calculatePair:bestCards rivalArray:bestCardsInfo.bestCards];
        }
        else if (rankBestHank == kTwoPair) 
        {
             return [self calculateTwoPair:bestCards rivalArray:bestCardsInfo.bestCards];
        }
        else if (rankBestHank == kThreeOfAKind) 
        {
            return [self calculateFirstCard:bestCards rivalArray:bestCardsInfo.bestCards];
        }
        else if(rankBestHank == kStraight)
        {
            return [self calculateFirstCard:bestCards rivalArray:bestCardsInfo.bestCards];
        }
        else if (rankBestHank == kFlush) 
        {
            return [self calculateHighCard:bestCards rivalArray:bestCardsInfo.bestCards];
        }
        else if (rankBestHank == kFullHouse) 
        {
            return [self calculateFirstCard:bestCards rivalArray:bestCardsInfo.bestCards];
        }
        else if (rankBestHank == kFourOfAKind) 
        {
            return [self calculateFirstCard:bestCards rivalArray:bestCardsInfo.bestCards];
        }
        else if (rankBestHank == kStraightFlush) 
        {
            return [self calculateFirstCard:bestCards rivalArray:bestCardsInfo.bestCards];
        }
        else if (rankBestHank == kRoyalFlush) 
        {
            return rCompareEqual;
        }

        return rCompareEqual;
    }
}
// check Staight, StaightFlush, FourOfKind, FullHouse, ThreeOfAKind
-(ResultCompareCards) calculateFirstCard:(NSArray*) myArray rivalArray:(NSArray*) rivalArray
{
    Card*myCard;
    Card*rivalCard;
    myCard = (Card*) [myArray objectAtIndex:0];
    rivalCard = (Card*) [rivalArray objectAtIndex:0];
    if([myCard rank] > [rivalCard rank])
    {
        return rCompareWin;
    } 
    else if ([myCard rank] < [rivalCard rank])
    {
        return rCompareLose;
    }
    return rCompareEqual;
}
// check HigheCard and Flush
-(ResultCompareCards) calculateHighCard:(NSArray*) myArray rivalArray:(NSArray*) rivalArray
{
    Card*myCard;
    Card*rivalCard;
    for(int i = 0; i< [myArray count]; i ++)
    {
        myCard = (Card*) [myArray objectAtIndex:i];
        rivalCard = (Card*) [rivalArray objectAtIndex:i];
        if([myCard rank] > [rivalCard rank])
        {
            return rCompareWin;
        } else if ([myCard rank] < [rivalCard rank]) {
            return rCompareLose;
        }
        
    }
    return rCompareEqual;
}
// check TwoPair
-(ResultCompareCards) calculateTwoPair:(NSArray*) myArray rivalArray:(NSArray*) rivalArray
{
    Card*myCard;
    Card*rivalCard;
    for(int i = 0; i< [myArray count]; i +=2)
    {
        myCard = (Card*) [myArray objectAtIndex:i];
        rivalCard = (Card*) [rivalArray objectAtIndex:i];
        if([myCard rank] > [rivalCard rank])
        {
            return rCompareWin;
        } else if ([myCard rank] < [rivalCard rank]) {
            return rCompareLose;
        }

    }
    return rCompareEqual;
}
// check Pair
-(ResultCompareCards) calculatePair:(NSArray*) myArray rivalArray:(NSArray*) rivalArray
{
    Card*myCard;
    Card*rivalCard;
    // check pair
    myCard = (Card*) [myArray objectAtIndex:0];
    rivalCard = (Card*) [rivalArray objectAtIndex:0];
    if([myCard rank] > [rivalCard rank])
    {
        return rCompareWin;
    } else if ([myCard rank] < [rivalCard rank]) {
        return rCompareLose;
    }
    // check highcard
    for(int i = 2; i< [myArray count]; i ++)
    {
        myCard = (Card*) [myArray objectAtIndex:i];
        rivalCard = (Card*) [rivalArray objectAtIndex:i];
        if([myCard rank] > [rivalCard rank])
        {
            return rCompareWin;
        } else if ([myCard rank] < [rivalCard rank]) {
            return rCompareLose;
        }
        
    }
    return rCompareEqual;
}

-(NSString*) debugBestHand
{
    if(rankBestHank == kRoyalFlush)
    {
        return @"RoyalFlush";
    }
    else if(rankBestHank == kStraightFlush)
    {
        return @"StraightFlush";
    }
    else if(rankBestHank == kFourOfAKind)
    {
        return @"FourOfAKind";
    }
    else if(rankBestHank == kFullHouse)
    {
        return @"FullHouse";
    }
    else if(rankBestHank == kFlush)
    {
        return @"Flush";
    }
    else if(rankBestHank == kStraight)
    {
        return @"Straight";
    }
    else if(rankBestHank == kThreeOfAKind)
    {
        return @"ThreeOfAKind";
    }
    else if(rankBestHank == kTwoPair)
    {
        return @"TwoPair";
    }
    else if(rankBestHank == kPair)
    {
        return @"Pair";
    }
    else // kHighCard
    {
        return @"HighCard";
    }
}
@end
